using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Camalon.ColorPicker
{
	/// <summary>
	/// Summary description for ColorTraker.
	/// </summary>
    [ToolboxItem(false)]
	public class ColorTracker : ColorTrackerBase //System.Windows.Forms.TrackBar
	{
		/// <summary> 
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public ColorTracker():base()
		{
	
			InitializeComponent();


			// TODO: Add any initialization after the InitializeComponent call
			ColorRenderingValue.ColorRangeChanged+=new EventHandler(ColorRenderingHelper_ColorRangeChanged);
			ColorRenderingValue.ValueChanged+=new EventHandler(ColorRenderingHelper_ValueChanged);
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this)).EndInit();

		}
		#endregion

		private void ColorRenderingHelper_ColorRangeChanged(object sender, EventArgs e)
		{

			if( _eventsLocked) return;


			if( ColorRenderingValue.ColorRange == ColorRange.Hue)
			{
				base.Maximum = 360;
				base.Minimum = 0;
			}
			else 
				if( ColorRenderingValue.ColorRange == ColorRange.Saturation || 
				ColorRenderingValue.ColorRange == ColorRange.Brightness )
			{
				base.Maximum = 100;
				base.Minimum = 0;
			}
			else 
			{
				base.Maximum = 255;
				base.Minimum = 0;
			}


			if( ColorRenderingValue.ColorRange == ColorRange.Hue)			base.Value = ColorRenderingValue.Hue;
			if( ColorRenderingValue.ColorRange == ColorRange.Saturation)	base.Value = ColorRenderingValue.Saturation;
			if( ColorRenderingValue.ColorRange == ColorRange.Brightness)	base.Value = ColorRenderingValue.Brightness;

			if( ColorRenderingValue.ColorRange == ColorRange.Red)			base.Value	= ColorRenderingValue.Red;
			if( ColorRenderingValue.ColorRange == ColorRange.Green)			base.Value	= ColorRenderingValue.Green;
			if( ColorRenderingValue.ColorRange == ColorRange.Blue)			base.Value	= ColorRenderingValue.Blue;

			this.Invalidate();

		}


		private void ColorRenderingHelper_ValueChanged(object sender, EventArgs e)
		{
			if( _eventsLocked) return;

			if( ColorRenderingValue.ColorRange == ColorRange.Hue)			base.Value = ColorRenderingValue.Hue;
			if( ColorRenderingValue.ColorRange == ColorRange.Saturation)	base.Value = ColorRenderingValue.Saturation;
			if( ColorRenderingValue.ColorRange == ColorRange.Brightness)	base.Value = ColorRenderingValue.Brightness;

			if( ColorRenderingValue.ColorRange == ColorRange.Red)			base.Value	= ColorRenderingValue.Red;
			if( ColorRenderingValue.ColorRange == ColorRange.Green)			base.Value	= ColorRenderingValue.Green;
			if( ColorRenderingValue.ColorRange == ColorRange.Blue)			base.Value	= ColorRenderingValue.Blue;

			this.Invalidate();
		}



		private bool _eventsLocked;
		protected override void ResetColorRenderingValue()
		{
			if( _eventsLocked) return;
			if( ColorRenderingValue.ColorRange == ColorRange.None) return;

			_eventsLocked = true;
			
			int value = (int)Math.Round( (double)this.Value );

			if( ColorRenderingValue.ColorRange == ColorRange.Red)		ColorRenderingValue.Red		= value;
			if( ColorRenderingValue.ColorRange == ColorRange.Green)		ColorRenderingValue.Green	= value;
			if( ColorRenderingValue.ColorRange == ColorRange.Blue)		ColorRenderingValue.Blue	= value;

			if( ColorRenderingValue.ColorRange == ColorRange.Hue)			ColorRenderingValue.Hue			= value;
			if( ColorRenderingValue.ColorRange == ColorRange.Saturation)	ColorRenderingValue.Saturation	= value;
			if( ColorRenderingValue.ColorRange == ColorRange.Brightness)	ColorRenderingValue.Brightness	= value;

			this.Invalidate();

			_eventsLocked = false;

		}


		#region DRAWING

		private static void DrawHueColorSlider( Graphics graphics, Rectangle colorRegion ) 
		{
			if( graphics == null) throw new ArgumentException("Graphics object can not be null","graphics");

			using ( LinearGradientBrush hueSliderBrush = new LinearGradientBrush( colorRegion, Color.Blue, Color.Red, 90f, false ) ) 
			{

				Color[] colorArray	= {	  Color.Red,
										  Color.Magenta,
										  Color.Blue,
										  Color.Cyan,
										  Color.FromArgb( 0, 255, 0 ),
										  Color.Yellow,
										  Color.Red };

				float[] posArray	= {   0.0f, 
										  0.1667f, 
										  0.3372f, 
										  0.502f, 
										  0.6686f, 
										  0.8313f, 
										  1.0f };

				ColorBlend colorBlend = new ColorBlend();
				colorBlend.Colors = colorArray;
				colorBlend.Positions = posArray;
				hueSliderBrush.InterpolationColors = colorBlend;

				graphics.FillRectangle( hueSliderBrush, colorRegion );
								
			}
		}


		private static  void UpdateSliderColorRGB( Graphics graphics, Rectangle colorRegion)//, RGB rgb, ColorRange colorRange ) 
		{
			if( graphics == null) throw new ArgumentNullException("Graphics object can not be null");
			
			ColorRange cr = ColorRenderingValue.ColorRange;

			if( cr == ColorRange.None) return;

			RGB rgb = ColorRenderingValue.RGB;

			int red		= rgb.Red;
			int green	= rgb.Green;
			int blue	= rgb.Blue;
				
			Color startColor;
			Color endColor;

			switch ( cr ) 
			{
					
				case ColorRange.Red:
					startColor = Color.FromArgb( 0, green, blue );
					endColor = Color.FromArgb( 255, green, blue );
					break;

				case ColorRange.Green:
					startColor = Color.FromArgb( red, 0, blue );
					endColor = Color.FromArgb( red, 255, blue );
					break;

				default:
					startColor = Color.FromArgb( red, green, 0 );
					endColor = Color.FromArgb( red, green, 255 );
					break;
			}

			using ( LinearGradientBrush lgb = new LinearGradientBrush( colorRegion, startColor, endColor, 270f ) ) 
				graphics.FillRectangle( lgb, colorRegion );
		}


		private static  void UpdateSliderColorHSB( Graphics graphics, Rectangle colorRegion)//, HSB hsb , ColorRange colorRange ) 
		{
			if( graphics == null) throw new ArgumentNullException("Graphics object can not be null");

			ColorRange cr = ColorRenderingValue.ColorRange;

			if( cr == ColorRange.None) return;
	
			HSB hsb = ColorRenderingValue.HSB;
			switch( cr )
			{
				case ColorRange.Hue:
					DrawHueColorSlider( graphics, colorRegion );
					break;
				case ColorRange.Brightness:
				{
					Color sColor = ColorConverter.HsbToColor( new HSB( hsb.Hue, hsb.Saturation, 100 ));
					Color eColor = ColorConverter.HsbToColor( new HSB( hsb.Hue, hsb.Saturation, 0 ));
							
					using ( LinearGradientBrush lgb = new LinearGradientBrush( colorRegion, sColor, eColor, 90f ) ) 
					graphics.FillRectangle( lgb, colorRegion );
					
					break;
				}
				default:
				{
					Color sColor = ColorConverter.HsbToColor( new HSB( hsb.Hue, 100, hsb.Brightness ));
					Color eColor = ColorConverter.HsbToColor( new HSB( hsb.Hue, 0, hsb.Brightness ));

					using ( LinearGradientBrush lgb = new LinearGradientBrush( colorRegion, sColor, eColor, 90f ) ) 
					graphics.FillRectangle( lgb, colorRegion );
					break;
				}
			}
		}
	

		protected override  void UpdateSliderColor( Graphics graphics, Rectangle colorRegion)
		{
			if( graphics == null) throw new ArgumentNullException("graphics","Graphics object can not be null");

			ColorRange cr = ColorRenderingValue.ColorRange;
			if( cr == ColorRange.None) return;

			if( cr == ColorRange.Red || cr == ColorRange.Green|| cr == ColorRange.Blue)
				UpdateSliderColorRGB( graphics, colorRegion);
			else
				UpdateSliderColorHSB( graphics, colorRegion);
		}


		#endregion DRAWING

	}
}
